﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;

namespace proLearningEnglish
{
    public partial class frmTesting : Form
    {
        private Test objTest;
        private string PupilName;
        private List<Question> lstQuestion = null;
        private PictureBox SelectedPictureBox = null;
        private ArrayList lstStruct = null;
        private int CurrentQuestion;
        private DateTime time;


        public frmTesting(Test t, string name)
        {
            this.CurrentQuestion = 1;
            this.objTest = t;
            this.PupilName = name;
            this.lstStruct = new ArrayList();
            InitializeComponent();            
            
        }

        private void frmTesting_Load(object sender, EventArgs e)
        {
            this.Text = "Học sinh: " + this.PupilName + " - " + "Đề: " + this.objTest.getName();
            this.lstQuestion = frmMain.objDataManager.getQuestionInTest(this.objTest);
            if (this.lstQuestion == null || this.lstQuestion.Count < 1)
            {
                MessageBox.Show("Đề kiểm tra rỗng !", "Lỗi");
                this.Dispose();
            }
            this.CurrentQuestion = 1;
            this.labNumberQuestion.Text = this.CurrentQuestion.ToString() + " / " + this.lstQuestion.Count.ToString();
            InitStruct();
            PaintQuestion();
            time = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 0, this.objTest.getTime(), 0);
            this.timer.Interval = 1000;
            timer.Start();
        }

        private IEnumerable<Control> GetAll(Control control, Type type)
        {
            var controls = control.Controls.Cast<Control>();

            return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls).Where(c => c.GetType() == type);
        }

        #region GroupBox 1

        private GroupBox groupBox1(SimpleWord sw, Point point)
        {
            GroupBox gb = new GroupBox();
            gb.Tag = sw;
            gb.Text = sw.getLabel();
            gb.Width = 150;
            gb.Height = 160;
            gb.Font = new System.Drawing.Font("Segoe Print", 11.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            gb.Click += new EventHandler(groupBox1_Click);
            gb.ControlAdded += new ControlEventHandler(groupBox1_ControlAdded);
            gb.ControlRemoved += new ControlEventHandler(groupBox1_ControlRemoved);
            gb.Location = point; // new Point(n * gb.Width + 10, d * gb.Height + 10);
            gb.ForeColor = Color.Yellow;
            return gb;
        }


        public void groupBox1_ControlRemoved(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            gb.Click += new EventHandler(groupBox1_Click);
            ((SimpleWord)gb.Tag).setSense(null);

        }

        public void groupBox1_ControlAdded(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            gb.Click -= new EventHandler(groupBox1_Click);
            ((SimpleWord)gb.Tag).setSense((WordSense)((ArrayList)this.SelectedPictureBox.Tag)[0]);
        }

        private void groupBox1_Click(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            if (this.SelectedPictureBox != null)
            {
                this.SelectedPictureBox.Location = new Point(10, 20);
                //this.SelectedPictureBox.MouseClick -= new MouseEventHandler(pictureBox_MouseClick);
                //this.SelectedPictureBox.DoubleClick += new EventHandler(pictureBox_DoubleClick);
                gb.Click -= new EventHandler(groupBox1_Click);
                gb.Controls.Add(this.SelectedPictureBox);
            }
        }

        #endregion
                
        #region GroupBox2

        private GroupBox groupBox2(SimpleWord sw, Point point, int width, int height)
        {
            GroupBox gb = new GroupBox();
            gb.Tag = sw; // new ArrayList() { sw, new List<WordSense>() };
            gb.Text = sw.getLabel();
            gb.Width = width;
            gb.Height = height;
            gb.Anchor = ((AnchorStyles)(AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right));
            gb.Font = new System.Drawing.Font("Segoe Print", 11.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            gb.Click += new EventHandler(groupBox2_Click);
            gb.ControlAdded += new ControlEventHandler(groupBox2_ControlAdded);
            gb.ControlRemoved += new ControlEventHandler(groupBox2_ControlRemoved);
            gb.Location = point; // new Point(n * gb.Width + 10, d * gb.Height + 10);
            gb.ForeColor = Color.Yellow;
            return gb;
        }        

        private void groupBox2_Click(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            if (this.SelectedPictureBox != null)
            {
                var pbs = this.GetAll(gb, typeof(PictureBox));
                
                if (!pbs.Contains(this.SelectedPictureBox))
                {
                    //int c = pbs.Count();                   
                    //this.SelectedPictureBox.Location = new Point(c * 130 + 10, 20);
                    gb.Controls.Add(this.SelectedPictureBox);
                }
            }
        }

        private void groupBox2_ControlAdded(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            var pbs = this.GetAll(gb, typeof(PictureBox));
            if (true)
            {
                int c = pbs.Count();
                int n = (int)(gb.Width / 140);
                int d = (int)(gb.Height / 140);
                //MessageBox.Show("c = " + c.ToString() + " nxd = " + n.ToString() + "x" + d.ToString());
                this.SelectedPictureBox.Location = new Point(((c - 1) % n) * 140, (d - 1) * 140 + 20);
                if (c >= n*d)
                {
                    gb.Height += 140;
                    this.SelectedPictureBox.Location = new Point(((c - 1) % n) * 140, (d - 1) * 140 + 20);
                    var lstGb = this.GetAll(this.splitContainer1.Panel1, typeof(GroupBox));
                    foreach (GroupBox g in lstGb)
                    {
                        if (g.Location.Y > gb.Location.Y)
                            g.Location = new Point(g.Location.X, g.Location.Y + 140);
                    }
                }
            }
        }

        private void groupBox2_ControlRemoved(object sender, EventArgs e)
        {
            GroupBox gb = sender as GroupBox;
            var pbs = this.GetAll(gb, typeof(PictureBox));
            int c = pbs.Count();
            int m = (int)(gb.Width / 140);
            int n = 0;
            int d = 0;
            foreach (PictureBox pb in pbs)
            {
                pb.Location = new Point(n * 140 , d * 140 + 20);
                n++;
                if (n >= m)
                {
                    n = 0;
                    d++;
                }
                if ((c / m + 1) < (gb.Height / 140))
                {                    
                    gb.Height -= 140;
                    var lstGb = this.GetAll(this.splitContainer1.Panel1, typeof(GroupBox));
                    foreach (GroupBox g in lstGb)
                    {
                        if (g.Location.Y > gb.Location.Y)
                            g.Location = new Point(g.Location.X, g.Location.Y - 140);
                    }
                }
            }
        }

        
        #endregion

        #region PictureBox

        private PictureBox pictureBox(WordSense s, Point point)
        {
            PictureBox pb = new PictureBox();
            pb.Width = 130;
            pb.Height = 130;
            pb.Location = point;
            pb.BackColor = Color.Transparent;
            pb.Tag = new ArrayList { s, pb.Location };
            pb.SizeMode = PictureBoxSizeMode.CenterImage;
            pb.MouseClick += new MouseEventHandler(pictureBox_MouseClick);
            pb.Image = Image.FromFile(Path.GetFullPath(frmMain.strPathPicture + s.getPicture()));
            return pb;
        }

        private void pictureBox_MouseClick(object sender, MouseEventArgs e)
        {
            PictureBox pb = sender as PictureBox;
            if (e.Button == MouseButtons.Left)
            {                
                var ct = GetAll(this.splitContainer1, typeof(PictureBox));
                foreach (PictureBox c in ct)
                {
                    c.BorderStyle = BorderStyle.None;
                }
                pb.BorderStyle = BorderStyle.FixedSingle;
                this.SelectedPictureBox = pb;
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (pb.Parent.GetType() == typeof(GroupBox))
                {
                    pb.Location = (Point)((ArrayList)pb.Tag)[1];
                    //pb.DoubleClick -= new EventHandler(pictureBox_DoubleClick);
                    pb.MouseClick += new MouseEventHandler(pictureBox_MouseClick);
                    this.splitContainer1.Panel2.Controls.Add(pb);
                    pictureBox_MouseClick(sender, e);
                }
            }
        }

        /*private void pictureBox_DoubleClick(object sender, EventArgs e)
        {
            PictureBox pb = sender as PictureBox;
            if (pb.Parent.GetType() == typeof(GroupBox))
            {
                pb.Location = (Point)((ArrayList)pb.Tag)[1];
                pb.DoubleClick -= new EventHandler(pictureBox_DoubleClick);
                pb.Click += new EventHandler(pictureBox_Click);               
                this.splitContainer1.Panel2.Controls.Add(pb);
                pictureBox_Click(sender, e);   
            }
        }*/

        #endregion

        private void InitStruct()
        {
            foreach (Question q in this.lstQuestion)
            {
                List<SimpleWord> lstWord = frmMain.objDataManager.getSimpleWordInQuestion(q);
                List<WordSense> lstSense = frmMain.objDataManager.getWordSenseInQuestion(q);
                List<GroupBox> lstGb = new List<GroupBox>();
                List<PictureBox> lstPb = new List<PictureBox>();
                if (q.getTypeInt() == 1)
                {
                    int c = (int)(this.splitContainer1.Panel1.Width / 150);
                    int n = 0;
                    int d = 0;
                    foreach (SimpleWord sw in lstWord)
                    {
                        lstGb.Add(groupBox1(sw, new Point(n * 150 + 10, d * 160 + 10)));
                        n++;
                        if (n >= c)
                        {
                            n = 0;
                            d++;
                        }
                    }
                    c = (int)(this.splitContainer1.Panel2.Width / 130);
                    n = 0;
                    d = 0;
                    foreach (WordSense s in lstSense)
                    {
                        lstPb.Add(pictureBox(s, new Point(n * 130 + 10, d * 130 + 10)));
                        n++;
                        if (n >= c)
                        {
                            n = 0;
                            d++;
                        }
                    }
                    this.lstStruct.Add(new ArrayList() { lstGb, lstPb });
                }
                else
                {
                    int d = 0;
                    foreach (SimpleWord sw in lstWord)
                    {
                        lstGb.Add(groupBox2(sw, new Point(10, d * 160 + 10), this.splitContainer1.Panel1.Width - 20, 160));
                        d++;
                    }
                    int c = (int)(this.splitContainer1.Panel2.Width / 130);
                    int n = 0;
                    d = 0;
                    foreach (WordSense s in lstSense)
                    {
                        lstPb.Add(pictureBox(s, new Point(n * 130 + 10, d * 130 + 10)));
                        n++;
                        if (n >= c)
                        {
                            n = 0;
                            d++;
                        }
                    }
                    this.lstStruct.Add(new ArrayList() { lstGb, lstPb });
                }
            }
        }

        private void splitContainer1_Panel1_Resize(object sender, EventArgs e)
        {
            if (this.lstQuestion != null && this.lstQuestion.Count > 0)
            {
                //this.splitContainer1.Panel1.Controls.Clear();
                ChangeLocation(this.lstQuestion[this.CurrentQuestion - 1]);
                //PaintQuestion();
            }
        }

        private void btnPrev_Click(object sender, EventArgs e)
        {
            if (this.CurrentQuestion > 1)
            {
                this.SelectedPictureBox = null;
                int count = this.lstQuestion.Count;
                this.CurrentQuestion--;
                if (this.CurrentQuestion == 1)
                {
                    this.btnPrev.Enabled = false;                    
                }
                this.labNumberQuestion.Text = this.CurrentQuestion.ToString() + " / " + count.ToString();
                if (this.CurrentQuestion < count)
                {
                    this.btnNext.Enabled = true;
                }
                PaintQuestion();
            }
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            int count = this.lstQuestion.Count;
            if (this.CurrentQuestion < count)
            {
                this.SelectedPictureBox = null;
                this.CurrentQuestion++;
                if (this.CurrentQuestion == count)
                {
                    this.btnNext.Enabled = false;                    
                }
                this.labNumberQuestion.Text = this.CurrentQuestion.ToString() + " / " + count.ToString();
                if (this.CurrentQuestion > 1)
                {
                    this.btnPrev.Enabled = true;
                }
            }
            PaintQuestion();
        }

        private void PaintQuestion()
        {
            this.splitContainer1.Panel1.Controls.Clear();
            this.splitContainer1.Panel2.Controls.Clear();
            List<GroupBox> lstGb = (List<GroupBox>)(((ArrayList)(this.lstStruct[this.CurrentQuestion - 1]))[0]);
            List<PictureBox> lstPb = (List<PictureBox>)(((ArrayList)(this.lstStruct[this.CurrentQuestion - 1]))[1]);
            for (int i = 0; i < lstGb.Count; i++)
            {
                this.splitContainer1.Panel1.Controls.Add(lstGb[i]);
            }
            var ct = GetAll(this.splitContainer1.Panel1, typeof(PictureBox));
            for (int i = 0; i < lstPb.Count; i++)
            {
                if (!ct.Contains(lstPb[i]))
                {
                    this.splitContainer1.Panel2.Controls.Add(lstPb[i]);
                }
            }
        }
        
        private void ChangeLocation(Question q)
        {
            //var ct = GetAll(this.splitContainer1.Panel2, typeof(PictureBox));
            List<GroupBox> lstGb = (List<GroupBox>)(((ArrayList)(this.lstStruct[this.CurrentQuestion - 1]))[0]);
            List<PictureBox> lstPb = (List<PictureBox>)(((ArrayList)(this.lstStruct[this.CurrentQuestion - 1]))[1]);
            if (q.getTypeInt() == 1)
            {
                int c = (int)(this.splitContainer1.Panel1.Width / 160);
                int n = 0;
                int d = 0;
                foreach (GroupBox gb in lstGb)
                {
                    gb.Location = new Point(n * 150 + 10, d * 160 + 10);
                    n++;
                    if (n >= c)
                    {
                        n = 0;
                        d++;
                    }
                }
                c = (int)(this.splitContainer1.Panel2.Width / 140);
                //Console.WriteLine("đếm: " + c.ToString());
                n = 0;
                d = 0;
                int x = 0;
                int y = 0;
                foreach (PictureBox pb in lstPb)
                {
                    if (this.splitContainer1.Panel2.Contains(pb))
                    {
                        pb.Location = new Point(n * 140, d * 140);
                        ((ArrayList)pb.Tag)[1] = pb.Location;
                    }
                    else { ((ArrayList)pb.Tag)[1] = new Point(n * 140, d * 140); }
                    n++;
                    if (n >= c)
                    {
                        n = 0;
                        d++;
                    }
                }
            }
            else
            {
                GroupBox currentGb = null;
                int n = 0;                
                int w = (int)(this.splitContainer1.Panel2.Width / 140);
                int d = 0;
                foreach (GroupBox gb in lstGb)
                {
                    int c = (int)(gb.Width / 140);
                    currentGb = gb;
                    gb.Width = this.splitContainer1.Panel1.Width - 20;
                    var pbs = GetAll(gb, typeof(PictureBox));
                    foreach (PictureBox pb in pbs)
                    {
                        pb.Location = new Point(n * 140, d * 140 + 20);
                        n++;
                        if (n >= c)
                        {
                            n = 0;
                            d++;
                        }
                    }
                }
                n = 0;
                d = 0;
                foreach (PictureBox pb in lstPb)
                {
                    ((ArrayList)pb.Tag)[1] = new Point(n * 140, d * 140);
                    if (this.splitContainer1.Panel2.Contains(pb))
                    {
                        pb.Location = (Point)((ArrayList)pb.Tag)[1];
                    }
                    n++;
                    if (n >= w)
                    {
                        n = 0;
                        d++;
                    }
                }
            }
        }
        //chấm điểm
        private int Scoring()
        {
            List<GroupBox> lstGb = new List<GroupBox>();
            int trueAnswer = 0;
            if (this.lstStruct.Count > 0)
            {
                for (int i = 0; i < this.lstStruct.Count; i++)
                {
                    //List of GroupBox
                    lstGb = (List<GroupBox>)(((ArrayList)this.lstStruct[i])[0]);
                    if (this.lstQuestion[i].getTypeInt() == 1)
                    {
                        int sum = 0;
                        for (int j = 0; j < lstGb.Count; j++)
                        {
                            SimpleWord sw = (SimpleWord)((GroupBox)lstGb[j]).Tag;
                            List<WordSense> temp = frmMain.objDataManager.getWordSenseOfWord(sw);

                            if (sw.getSense() != null)
                            {
                                foreach (WordSense w in temp)
                                {
                                    if (w.getID().Equals(sw.getSense().getID()))
                                    {
                                        sum++;
                                        break;
                                    }
                                }
                            }
                        }
                        if (sum == lstGb.Count)
                            trueAnswer++;
                    }
                    else
                    {
                        int t = 0;
                        int numpb = ((List<PictureBox>)((ArrayList)this.lstStruct[i])[1]).Count;
                        Console.WriteLine(numpb);
                        int dempb = 0;
                        foreach (GroupBox gb in lstGb)
                        {                            
                            var pbs = GetAll(gb, typeof(PictureBox));
                            Console.WriteLine(pbs.Count());
                            dempb += pbs.Count();
                            List<WordSense> lstSense = frmMain.objDataManager.getWordSenseOfWord((SimpleWord)gb.Tag);
                            List<WordSense> lstS = new List<WordSense>();
                            foreach(WordSense s in lstSense)
                            {
                                //Console.WriteLine(s.getLabel());
                                List<WordSense> sense = frmMain.objDataManager.getIsAChildWordSenseNodes(s);
                                //Console.WriteLine(sense.Count.ToString());
                                lstS.AddRange(sense);               
                            }
                            //Console.WriteLine(lstS.Count.ToString());
                            int c = 0;
                            foreach (PictureBox pb in pbs)
                            {
                                //if (lstS.Contains((WordSense)((ArrayList)pb.Tag)[0]))
                                foreach(WordSense s in lstS)
                                {
                                    //Console.WriteLine("So sánh: ");
                                    //Console.WriteLine(s.getID());
                                    //Console.WriteLine(((WordSense)((ArrayList)pb.Tag)[0]).getID());
                                    if (s.getID() == ((WordSense)((ArrayList)pb.Tag)[0]).getID())
                                    {
                                        c++;
                                        break;
                                    }
                                }
                            }
                            if (c == pbs.Count())
                                t++;
                        }
                        Console.WriteLine("num : " + numpb.ToString() + " : dem " + dempb.ToString());
                        if (t == lstGb.Count && dempb == numpb)
                            trueAnswer++;
                    }
                }
            }
            return trueAnswer;
        }

        private void btnFinish_Click(object sender, EventArgs e)
        {
            MessageBox.Show(this.Scoring().ToString());
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            TimeSpan timeSpan = new TimeSpan(0, 0, 1);
            time = time.Subtract(timeSpan);
            this.labTime.Text = "Thời gian: " + string.Format("{0}:{1}", time.Minute, time.Second);
            if (time.Minute == 0 && time.Second == 0)
            {
                btnFinish_Click(sender, e);
                this.timer.Stop();
            }
        }
    }
}
